package models.base;

import ext.jpa.UUIDModel;
import facade.vo.base.UserVO;
import helper.GlobalConfig;
import helper.TextHelper;
import jodd.util.RandomString;
import models.constants.DeletedStatus;
import models.enums.AvailableStatus;
import org.apache.commons.lang.StringUtils;
import org.hibernate.SQLQuery;
import org.hibernate.annotations.Index;
import org.hibernate.transform.Transformers;
import play.data.validation.Required;
import play.db.jpa.JPA;

import javax.persistence.*;
import java.util.*;

/**
 * 员工用户信息
 */
@Entity
@Table(name = "admin_users", schema = GlobalConfig.MIGAO_DB_SCHEMA)
@org.hibernate.annotations.Table(
        appliesTo = "admin_users",
        indexes = {
                @Index(name = "idx_users_email", columnNames = "email"),
                @Index(name = "idx_users_mobile", columnNames = "mobile"),
                @Index(name = "idx_users_created_at", columnNames = "created_at")
        }
)
public class AdminUser extends UUIDModel {

    private static final long serialVersionUID = -2599690107062743622L;

    /**
     * 所属公司.
     */
    @ManyToOne
    @JoinColumn(name = "corp_id", nullable = true)
    public Corp corp;

    /**
     * 员工登录名.
     *
     * 管理端的帐号，企业内必须唯一。长度为1~64个字符.
     * 对应企业号的userId.  公众号模式时可为空.
     */
    @Column(name = "login_name", length = 64)
    public String loginName;

    /**
     * 登录密码
     */
    @Column(name = "password", length = 50)
    public String password;

    @Column(name = "password_salt", length = 50)
    public String passwordSalt;  // MD5加密的随机数 防止 MD5 暴力破解   md5(password+passwordSalt)     123456adcs      1234561123

    /**
     * 用户姓名.
     */
    @Required
    @Column(name = "name", length = 64)
    public String name;

    /**
     * 手机号码.
     *
     * 企业内必须唯一，mobile/weixinid/email三者不能同时为空.
     */
    @Column(name = "mobile", length = 20)
    public String mobile;

    /**
     * 邮箱.
     *
     * 长度为0~64个字符。企业内必须唯一
     */
    @Required
    @Column(name = "email", length = 100)
    public String email;

    /**
     * 是否是超级管理员，超级管理员用于系统维护使用
     * 超级管理员由系统默认生成，不可手动创建或者注册生成
     * 该字段不可编辑
     */
    @Column(name = "is_super_admin")
    public Boolean isSuperAdmin = Boolean.FALSE;

    @Column(name = "is_admin")
    public Boolean isAdmin = Boolean.FALSE;

    /**
     * 用户状态.
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "status")
    public AvailableStatus status = AvailableStatus.AVAILABLE;


    /**
     * 备注
     */
    @Column(name="remark")
    public String remark ;

    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    @Column(name = "deleted")
    public DeletedStatus deleted = DeletedStatus.UN_DELETED;

    /**
     * 创建人.
     */
    @Column(name = "create_user_id")
    public String createUserId;


    /**
     * 创建时间.
     */
    @Column(name = "created_at")
    public Date createdAt;


    /**
     * 修改人.
     */
    @Column(name = "modify_user_id")
    public String modifyUserId;

    /**
     * 更新时间.
     */
    @Column(name = "modify_at")
    public Date modifyAt;

    public String getId(){
        return this.id;
    }

    /**
     * 是否活动用户.
     */
    @Transient
    public boolean isActive() {
        return this.deleted != DeletedStatus.DELETED && this.status == AvailableStatus.AVAILABLE;
    }

    @Transient
    public boolean isAdmin() {
        // 兼容性
        return isActive() && (Boolean.TRUE.equals(this.isSuperAdmin) || Boolean.TRUE.equals(this.isAdmin));
    }


    @Transient
    private Set<String> _roleSet;

    @Transient
    public Set<String> getRoleSet() {
        return _roleSet;
    }
    @Transient
    public void setRoleSet(Set<String> set) {
        this._roleSet = set;
    }

    @Transient
    public boolean isDiySuperAdmin() {
        return GlobalConfig.SUPER_USER_IDS.contains(this.id);
    }


    /***************以下为用户管理用到的方法******************************/

    public static Map<String,Object> findByCondition(String key, int pageNumber, int pageSize) {
        StringBuilder sqlSelect = new StringBuilder("select u.id,u.name,u.mobile,u.email,u.login_name as loginName,u.mechanism_id as mechanismId,m.name as mechanismName,u.store_id as storeId,s.name as storeName,u.status,u.created_at as createdAt from admin_users u left join mechanisms m on m.id=u.mechanism_id left join stores s on s.id=u.store_id");
        StringBuilder sqlCount = new StringBuilder("select count(u.id) from admin_users u left join mechanisms m on m.id=u.mechanism_id left join stores s on u.store_id=s.id ");
        StringBuilder sqlWhere = new StringBuilder(" where u.deleted=").append(DeletedStatus.UN_DELETED.getValue()).append(" and u.is_super_admin=0 ");
        StringBuilder sqlOrder = new StringBuilder(" order by u.created_at desc ");

//        sqlWhere.append(" and u.status='").append(AvailableStatus.AVAILABLE.getValue()).append("'");
        if(StringUtils.isNotEmpty(key)) {
            sqlWhere.append(" and (u.name like '%").append(key).append("%' or u.mobile like '%").append(key).append("%' or u.login_name like '%").append(key).append("%') ");
        }
        Map<String,Object> pageMap = new HashMap<>();
        pageMap.put("code",0);
        Query queryCount = JPA.em().createNativeQuery(sqlCount.append(sqlWhere).toString());
        int total = new Integer(String.valueOf(queryCount.getSingleResult()));
        pageMap.put("totalCount",total);
        pageMap.put("pageNumber",pageNumber);
        pageMap.put("pageSize",pageSize);
        double totalPage = Math.ceil(total/pageSize);

        pageMap.put("totalPage",new Double(totalPage).intValue());
        int page = pageNumber>0?(pageNumber-1):0;
        Query query = JPA.em().createNativeQuery(sqlSelect.append(sqlWhere).append(sqlOrder).append(" limit ").append(page*pageSize).append(",").append(pageSize).toString());
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List<AdminUser> voList = query.getResultList();
        pageMap.put("data",voList);
        return pageMap;
    }

    public static AdminUser findOne(String id){
        if(StringUtils.isEmpty(id)) return null;
        return find("deleted=? and id=?",DeletedStatus.UN_DELETED,id).first();
    }

    /**
     * 根据手机号查询用户账号 确保手机号唯一性
     * @param mobile 手机号
     * @return
     */
    public static AdminUser findByMobile(String mobile,String id) {
        if (StringUtils.isEmpty(mobile)) return null;
        if (StringUtils.isEmpty(id))
            return find("deleted=?1 and mobile=?2", DeletedStatus.UN_DELETED, mobile).first();
        else
            return find("deleted=?1 and mobile=?2 and id !=?3", DeletedStatus.UN_DELETED, mobile, id).first();
    }

    /**
     * 根据email查询用户账号 确保邮箱唯一性
     * @param email 邮箱
     * @return
     */
    public static AdminUser findByEmail(String email){
        if(StringUtils.isEmpty(email)) return null;
        return find("deleted=? and email=?",DeletedStatus.UN_DELETED,email).first();
    }
    /**
     * 根据登录名查询用户账号 确保登录名唯一性
     * @param loginName  登录名
     * @return
     */
    public static AdminUser findByLoginName(String loginName){
        if(StringUtils.isEmpty(loginName)) return null;
        return find("deleted=?1 and loginName=?2",DeletedStatus.UN_DELETED,loginName).first();
    }

    /**
     * 修改密码
     * @param newPassword 新密码
     */
    public void updatePassword(String newPassword) {
        this.passwordSalt = RandomString.getInstance().randomAlphaNumeric(48);
        this.password = TextHelper.encryptPassword(newPassword, this.passwordSalt);
        this.save();
    }

    public static Long countValidUserForCorp(Corp corp) {
        if (corp == null) {
            return 0L;
        }
        return count("corp=?1 and deleted=?2 and status=?3", corp, DeletedStatus.UN_DELETED, AvailableStatus.AVAILABLE);
    }

    public static List<AdminUser> findAdminForCorp(Corp corp, int size) {
        if (corp == null) {
            return Collections.emptyList();
        }
        return find("corp=?1 and deleted=?2 and isAdmin=?3", corp, DeletedStatus.UN_DELETED, Boolean.TRUE).fetch(size);
    }
    public static List<UserVO> findByRole(String roleId) {
        if (StringUtils.isEmpty(roleId)) {
            return Collections.emptyList();
        }

        String sqlSelect = "SELECT u.id,u.name,u.login_name as loginName,u.email,u.mobile,u.corp_id as corpId,c.name as corpName,u.mechanism_id as mechanismId,m.name as mechanismName,u.store_id as storeId,s.name as storeName from admin_users u left join corps c on u.corp_id=c.id left join mechanisms m on u.mechanism_id=m.id left join stores s on u.store_id=s.id left join admin_user_roles ur on u.id=ur.user_id where u.deleted=0 and u.status=0 and ur.role_id='"+roleId+"'";
        System.out.println(sqlSelect);
        Query query = JPA.em().createNativeQuery(sqlSelect);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query.getResultList();
    }

}
